package com.bytz.modules.cms.order.schedule;

import cn.hutool.core.bean.copier.BeanCopier;
import cn.hutool.core.bean.copier.CopyOptions;
import com.bytz.common.system.vo.LoginUser;
import com.bytz.common.util.SecurityUtils;
import com.bytz.modules.bpm.client.model.StartProcessResult;
import com.bytz.modules.cms.common.service.CmsConfigService;
import com.bytz.modules.cms.order.constant.OrderConstants;
import com.bytz.modules.cms.order.entity.Order;
import com.bytz.modules.cms.order.model.OrderSaveRo;
import com.bytz.modules.cms.order.service.IOrderFlowService;
import com.bytz.modules.cms.order.service.IOrderService;
import com.bytz.modules.system.service.ISysUserService;
import com.bytz.modules.system.vo.SysUserVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @program: cms-backend
 * @description:
 * @author: KyleWang
 * @create: 2022-10-25 14:21
 **/
@Component
@Slf4j
public class OrderStartProcessSchedule implements Job {

    @Autowired
    IOrderService orderService;
    @Autowired
    IOrderFlowService orderFlowService;
    @Autowired
    ISysUserService sysUserService;
    @Autowired
    private CmsConfigService configService;
    public static final BigDecimal FIFTY_THOUSAND = BigDecimal.valueOf(50000);
    public static final BigDecimal TWO_HUNDRED_THOUSAND = BigDecimal.valueOf(200000);

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        List<Order> orderByStatus = orderService.getOrderByStatus(OrderConstants.OrderStatus.YI_TI_JIAO);

        Map<Boolean, List<Order>> needProcess = orderByStatus.stream().collect(Collectors.groupingBy(order -> {

            if (OrderConstants.OrderType.STANDARD.equals(order.getOrderType())) {
                BigDecimal taxRate = configService.getGlobal().getTaxRate();
                BigDecimal noTaxPrice =  order.getTotalPrice().divide(taxRate.add(BigDecimal.valueOf(1)), 2, RoundingMode.HALF_UP);
                // 标准订单 VTS 未税价格大于5万进入流程
                if (StringUtils.equals(order.getProductLineCode(), "VTS")) {
                    return FIFTY_THOUSAND.compareTo(noTaxPrice) < 0;
                } else {
                    // IV SV 未税价格大于20万进入流程
                    return TWO_HUNDRED_THOUSAND.compareTo(noTaxPrice) < 0;
                }
            } else {
                return true;
            }
        }));
        List<Order> doProcessOrders = needProcess.get(Boolean.TRUE);
        if (CollectionUtils.isNotEmpty(doProcessOrders)) {

            List<String> sellers = doProcessOrders.stream().map(Order::getSalesId).filter(StringUtils::isNotBlank).distinct().collect(Collectors.toList());
            List<SysUserVo> sellerUsers = sysUserService.getUsersByIds(sellers);
            Map<String, LoginUser> loginUserMap = sellerUsers.stream().filter(Objects::nonNull).map(sysUserVo -> {
                LoginUser loginUser = new LoginUser();
                BeanCopier.create(sysUserVo, loginUser, CopyOptions.create().ignoreNullValue()).copy();
                return loginUser;
            }).collect(Collectors.toMap(LoginUser::getId, Function.identity()));
            Map<String, List<Order>> collect = doProcessOrders
                    .stream().collect(Collectors.groupingBy(Order::getSalesId));
            collect.forEach((k, orders) -> {
                if (StringUtils.isNoneBlank(k)) {
                    LoginUser loginUser = loginUserMap.get(k);
                    if (loginUser != null) {
                        SecurityUtils.setLoginUser(loginUser);
                    }
                    orders.forEach(order -> {
                        OrderSaveRo orderSaveRo = new OrderSaveRo();
                        BeanCopier.create(order, orderSaveRo, CopyOptions.create().ignoreNullValue()).copy();
                        try {
                            StartProcessResult startProcessResult = orderFlowService.startProcess(orderSaveRo, null, loginUser);
                            log.info("流程发起成功 order id:{};result:{}", order.getId(), startProcessResult);
                        } catch (Exception e) {
                            log.error(String.format("发起订单流程失败 orderId:%s", order.getId()), e);
                        }
                    });
                    SecurityContextHolder.getContext().setAuthentication(null);

                } else {
                    log.info("找不到销售人员 order ids:{}", orders.stream().map(Order::getId).collect(Collectors.joining(",")));
                }
            });
        }

        List<Order> notProcessOrders = needProcess.get(Boolean.FALSE);
        if (CollectionUtils.isNotEmpty(notProcessOrders)) {
            notProcessOrders.forEach(order -> {
                order.setStatus(OrderConstants.OrderStatus.SHEN_HE_TONG_GUO);
                order.setCompleteTime(LocalDateTime.now());
            });
            log.info("{}个订单不发流程，直接盖章，ids:{}", notProcessOrders.size(),
                    notProcessOrders.stream().map(Order::getId).collect(Collectors.joining(",")));
            orderService.updateBatchById(notProcessOrders);
        }
    }
}